/**
 * 
 */
package org.t2.game.server.module.mail;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.gaming.fakecmd.annotation.InternalCmd;
import org.gaming.fakecmd.annotation.PlayerCmd;
import org.gaming.prefab.thing.NoticeType;
import org.gaming.service.asserts.Asserts;
import org.gaming.tool.DateTimeUtil;
import org.gaming.tool.GsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.t2.game.server.foundation.player.PlayerContext;
import org.t2.game.server.module.mail.api.RewardThing;
import org.t2.game.server.module.mail.message.SystemMailMessage;
import org.t2.game.server.module.mail.model.Mail;
import org.t2.game.server.module.mail.service.MailService;
import org.t2.game.server.module.mail.service.MailSystemService;
import org.t2.game.server.module.tips.TipsCode;

import pb.t2.protobuf.mail.Mail.MailDeleteRequest;
import pb.t2.protobuf.mail.Mail.MailDeleteResponse;
import pb.t2.protobuf.mail.Mail.MailInfoRequest;
import pb.t2.protobuf.mail.Mail.MailInfoResponse;
import pb.t2.protobuf.mail.Mail.MailReadAllRequest;
import pb.t2.protobuf.mail.Mail.MailReadAllResponse;
import pb.t2.protobuf.mail.Mail.MailReadRequest;
import pb.t2.protobuf.mail.Mail.MailReadResponse;
import pb.t2.protobuf.mail.Mail.MailReceiveAllRequest;
import pb.t2.protobuf.mail.Mail.MailReceiveAllResponse;
import pb.t2.protobuf.mail.Mail.MailReceiveRequest;
import pb.t2.protobuf.mail.Mail.MailReceiveResponse;

/**
 * 
 */
@Controller
public class MailHandler {

	@Autowired
	private MailService mailService;
	@Autowired
	private MailSystemService mailSystemService;

	@PlayerCmd
	public MailInfoResponse info(PlayerContext playerContext, MailInfoRequest request) {
		MailInfoResponse.Builder response = MailInfoResponse.newBuilder();
		List<Mail> mails = mailService.mails(playerContext.getId());
		//过期的邮件
		List<Mail> expireMails = new ArrayList<>();
		long now = DateTimeUtil.currMillis();
		for (Mail mail : mails) {
			List<RewardThing> rewardThings = GsonUtil.getList(mail.getAttachment(), RewardThing.class);
			if(rewardThings.isEmpty() && now > mail.getExpireTime()) {
				expireMails.add(mail);
				continue;
			}
			if(!rewardThings.isEmpty() && mail.isReceive() && now > mail.getExpireTime()) {
				expireMails.add(mail);
				continue;
			}
			response.addMails(mailService.build(mail));
		}
		if(!expireMails.isEmpty()) {
			mailService.delete(expireMails);
		}
		return response.build();
	}

	@PlayerCmd
	public MailReadResponse read(PlayerContext playerContext, MailReadRequest request) {
		Mail mail = mailService.getMail(playerContext.getId(), request.getId());
        Asserts.isTrue(mail != null, TipsCode.MAIL_NOT_EXIST, request.getId());

        if (!mail.isRead()) {
            mail.markRead();
            mailService.update(mail);
        }

        MailReadResponse.Builder response = MailReadResponse.newBuilder();
        response.setId(mail.getId());
        return response.build();
	}

	@PlayerCmd
	public MailReadAllResponse readAll(PlayerContext playerContext, MailReadAllRequest request) {
		List<Mail> mails = mailService.mails(playerContext.getId());
		List<Mail> updateList = new ArrayList<>();
		for(Mail mail : mails) {
			if(!mail.isRead()) {
				mail.markRead();
				updateList.add(mail);
			}
		}
		mailService.update(updateList);
		
		return MailReadAllResponse.getDefaultInstance();
	}

	@PlayerCmd
	public MailReceiveResponse receive(PlayerContext playerContext, MailReceiveRequest request) {
		Mail mail = mailService.getMail(playerContext.getId(), request.getId());
        Asserts.isTrue(mail != null, TipsCode.MAIL_NOT_EXIST, request.getId());

        if (!mail.isReceive()) {
            mail.markReceive();
            mailService.update(mail);
        }
        
        MailReceiveResponse.Builder response = MailReceiveResponse.newBuilder();
        response.setId(mail.getId());
        return response.build();
	}

	@PlayerCmd
	public MailReceiveAllResponse receiveAll(PlayerContext playerContext, MailReceiveAllRequest request) {
		List<Mail> mails = mailService.mails(playerContext.getId());
		List<Mail> updateList = new ArrayList<>();
		for(Mail mail : mails) {
			if(!mail.isReceive()) {
				mail.markReceive();
				updateList.add(mail);
			}
		}
		mailService.update(updateList);
		
		return MailReceiveAllResponse.getDefaultInstance();
	}

	@PlayerCmd
	public MailDeleteResponse delete(PlayerContext playerContext, MailDeleteRequest request) {
		Set<Long> deleteIds = new HashSet<>(request.getIdsList());
		
		List<Mail> mails = mailService.mails(playerContext.getId());
		List<Mail> deleteList = new ArrayList<>();
		for(Mail mail : mails) {
			if(deleteIds.contains(mail.getId())) {
				deleteList.add(mail);
			}
		}
		mailService.delete(deleteList);
		
		MailDeleteResponse.Builder response = MailDeleteResponse.newBuilder();
		response.addAllIds(deleteIds);
		return response.build();
	}
	
	@InternalCmd
	public void handle(SystemMailMessage message) {
		List<Mail> newMails = mailSystemService.pullMailFromSystem(message.getPlayerId());
    	if(newMails.isEmpty()) {
    		return;
    	}
    	mailService.sendMail(newMails, NoticeType.NORMAL);
	}
}
